<template>
  <div>
    <div class="plane" id="plane">
      <img src="@/assets/images/plane.png" />
    </div>
    <div class="model">
      <div class="model-item model-left">
        <moldVue
          :directionX="modelParmas.directionX"
          :directionY="modelParmas.directionY"
        />
        <pushVue :yaoganX="modelParmas.yaoganX" />
      </div>
      <div class="model-item model-right">
        <pedalVue :pedalX="modelParmas.pedalX" />
      </div>
    </div>
  </div>
</template>

<script>
import { mapGetters } from "vuex";
import moldVue from "@/components/modelComponents/moldVue/mold.vue";
import pedalVue from "@/components/modelComponents/pedal/pedal.vue";
import pubsub from "pubsub-js";
import pushVue from "@/components/modelComponents/push/push.vue";
export default {
  components: {
    moldVue,
    pedalVue,
    pushVue,
  },
  data() {
    return {
      destoryFun: "", // 销毁对象
      plane: null,
      situationIndex: -1,
      speedIndex: -1,
      balanceIndex: -1,
      requestAnimationFrameId: null,
      requestAnimationSpeedFrameId: null,
      requestAnimationBalanceFrameId: null,
      gamepads: [],
      gameContiner: null,
      planeOffset: {
        planeOffsetX: 0,
        planeOffsetY: 0,
      },
      startTime: null,
    };
  },
  computed: {
    ...mapGetters([
      "rockerSpeed",
      "modelParmas",
      "getWebSocket",
      "getConnectionStatus",
    ]),
  },
  beforeDestroy() {
    pubsub.unsubscribe(this.destoryFun);
  },
  created() {},
  mounted() {
    this.destoryFun = pubsub.subscribe("user", () => {
      console.log("监听到事件user");
      // this.destroy();
      setTimeout(() => {
        pubsub.publish("refshow2");
      }, 200);
    });
    this.initplane();
    pubsub.subscribe("refshow1", () => {
      window.location.reload();
    });
  },
  methods: {
    cancleInterVal() {
      clearInterval(this.startTime);
    },
    actionGamepe() {
      let count = 0;
      this.startTime = setInterval(() => {
        let planeJoystick = {
          id: count++,
          code: "planeJoystick",
          time: new Date().getTime(),
          planeOffsetX: this.planeOffset.planeOffsetX,
          planeOffsetY: this.planeOffset.planeOffsetY,
        };
        if (this.getConnectionStatus) {
          this.getWebSocket.send(JSON.stringify(planeJoystick));
        }
      }, 56);
    },
    initplane() {
      this.plane = document.getElementById("plane");
      const planeOffset = {
        planeOffsetX: this.plane.style.left,
        planeOffsetY: this.plane.style.top,
      };
      this.$store.commit("updateFlyDataKey", planeOffset);
      this.gameContiner = this.$parent.$el;
      window.addEventListener("gamepadconnected", this.gamepadConnected);
      window.addEventListener("gamepaddisconnected", this.gamepadDisconnected);
    },
    destroy() {
      console.log("游戏一移除监听");
      window.removeEventListener("gamepadconnected", this.gamepadConnected);
      window.removeEventListener(
        "gamepaddisconnected",
        this.gamepadDisconnected
      );
      this.stopSituationBalanceGamepad();
      this.stopSituationGamepad();
      this.stopSpeedGamepad();
    },
    gamepadConnected(e) {
      this.gamepads = navigator.getGamepads().filter((item) => item != null);
      this.updateControllerInfo();
    },
    gamepadDisconnected(e) {
      var index = this.gamepads.indexOf(e.gamepad);
      if (index !== -1) {
        this.gamepads.splice(index, 1);
        this.updateControllerInfo();
      }
    },
    updateControllerInfo() {
      for (var i = 0; i < this.gamepads.length; i++) {
        var gamepad = this.gamepads[i];
        if (gamepad.id.includes("Joystick")) {
          this.situationIndex = i;
          this.startSituationGamepad();
        } else if (gamepad.id.includes("Throttle")) {
          this.speedIndex = i;
          this.startSpeedGamepad();
        } else if (gamepad.id.includes("T-Pendular")) {
          this.balanceIndex = i;
          this.startSituationBalanceGamepad();
        } else {
          console.log("控制器类型: 未知");
        }
      }
    },
    //平衡控制器开始方法
    startSituationBalanceGamepad() {
      if (this.requestAnimationBalanceFrameId) {
        cancelAnimationFrame(this.requestAnimationBalanceFrameId);
      }
      console.log("开始轮询平衡控制器的输入");
      this.requestAnimationBalanceFrameId = requestAnimationFrame(
        this.balanceGamepad
      );
    },
    //平衡控制器停止方法
    stopSituationBalanceGamepad() {
      console.log("停止轮询平衡控制器的输入");
      cancelAnimationFrame(this.requestAnimationBalanceFrameId);
    },
    //方向控制器开始方法
    startSituationGamepad() {
      if (this.requestAnimationFrameId) {
        cancelAnimationFrame(this.requestAnimationFrameId);
      }
      console.log("开始轮询方向控制器的输入");
      this.requestAnimationFrameId = requestAnimationFrame(this.pollGamepad);
    },
    //方向控制器停止方法
    stopSituationGamepad() {
      console.log("停止轮询方向控制器的输入");
      cancelAnimationFrame(this.requestAnimationFrameId);
    },
    //速度控制器开始方法
    startSpeedGamepad() {
      if (this.requestAnimationSpeedFrameId) {
        cancelAnimationFrame(this.requestAnimationSpeedFrameId);
      }
      console.log("开始轮询速度控制器的输入");
      this.requestAnimationSpeedFrameId = requestAnimationFrame(
        this.speedGamepad
      );
    },
    //速度控制器停止方法
    stopSpeedGamepad() {
      console.log("停止轮询速度控制器的输入");
      cancelAnimationFrame(this.requestAnimationSpeedFrameId);
    },
    //平衡控制器方法
    balanceGamepad() {
      var gamepads = navigator.getGamepads().filter((item) => item != null);
      if (!gamepads || !gamepads[this.balanceIndex]) {
        console.log("平衡控制器未连接或无效，停止轮询", gamepads);
        this.stopSituationBalanceGamepad();
        return;
      }
      var gamepad = gamepads[this.balanceIndex];
      let axis = gamepad.axes[2].toFixed(2);
      this.$store.commit("updateModelParmas", { pedalX: axis.toString() });
      // console.log("axis:", axis);
      this.$store.commit("setTroubdSpeed", axis);
      this.requestAnimationBalanceFrameId = requestAnimationFrame(
        this.balanceGamepad
      );
    },
    //方向控制器方法
    pollGamepad() {
      var gamepads = navigator.getGamepads().filter((item) => item != null);
      if (!gamepads || !gamepads[this.situationIndex]) {
        console.log(
          "方向控制器未连接或无效，停止轮询",
          gamepads,
          this.situationIndex
        );
        this.stopSituationGamepad();
        return;
      }
      var gamepad = gamepads[this.situationIndex];
      var axisX = gamepad.axes[0];
      var axisY = gamepad.axes[1];
      this.$store.commit("updateModelParmas", {
        directionX: axisX.toFixed(1).toString(),
        directionY: axisY.toFixed(1).toString(),
      });
      // console.log("游戏一axisX:", axisX, "axisY:", axisY);
      this.moveBall(axisX, axisY);
      for (var j = 0; j < gamepad.buttons.length; j++) {
        var button = gamepad.buttons[j];
        if (button.pressed) {
          console.log("游戏方向控制器上的按钮 " + j + " 被按下");
        }
      }
      this.requestAnimationFrameId = requestAnimationFrame(this.pollGamepad);
    },
    //速度控制器方法
    speedGamepad() {
      var gamepads = navigator.getGamepads().filter((item) => item != null);
      if (!gamepads || !gamepads[this.speedIndex]) {
        console.log(
          "速度控制器未连接或无效，停止轮询",
          gamepads,
          this.speedIndex
        );
        this.stopSpeedGamepad();
        return;
      }
      var gamepad = gamepads[this.speedIndex];
      var axisX = gamepad.axes[2];
      var axisY = gamepad.axes[5];
      this.$store.commit("updateModelParmas", {
        yaoganX: axisX.toFixed(2).toString(),
      });
      axisY = ((-axisY + 1) * 5).toFixed(2);
      axisX = ((-axisX + 1) * 5).toFixed(2);
      this.$store.commit("setBgSpeed", axisX);
      // console.log("速度", axisX);
      for (var j = 0; j < gamepad.buttons.length; j++) {
        var button = gamepad.buttons[j];
        if (button.pressed) {
          console.log("游戏速度控制器上的按钮 " + j + " 被按下");
        }
      }
      this.requestAnimationSpeedFrameId = requestAnimationFrame(
        this.speedGamepad
      );
    },
    //控制模型移动
    moveBall(axisX, axisY) {
      let rotateZ = axisX.toFixed(1) * 90;
      let rotateX = axisY.toFixed(1) * 30;
      document.documentElement.style.setProperty(
        "--rotateZ-plane",
        `${rotateZ}deg`
      );
      document.documentElement.style.setProperty(
        "--rotateX-plane",
        `${-rotateX}deg`
      );
      var newX = this.plane.offsetLeft + axisX * this.rockerSpeed * 2;
      var newY = this.plane.offsetTop + axisY * this.rockerSpeed * 2;
      newX = Math.max(
        0,
        Math.min(this.gameContiner.offsetWidth - this.plane.offsetWidth, newX)
      );
      newY = Math.max(
        0,
        Math.min(this.gameContiner.offsetHeight - this.plane.offsetHeight, newY)
      );
      this.plane.style.left = newX + "px";
      // console.log(newY);
      // let viewHeight =
      //   document.querySelector("#plane").parentElement.previousElementSibling
      //     .children[0].offsetTop;
      // if (viewHeight >= 0) {
      //   this.plane.style.top = newY + "px";
      // }
      this.planeOffset.planeOffsetX = newX.toFixed(2);
      this.planeOffset.planeOffsetY = newY.toFixed(2);

      this.$store.commit("updateFlyDataKey", this.planeOffset);
    },
  },
};
</script>

<style lang="scss" scoped>
.plane {
  width: 120px;
  height: 160px;
  position: absolute;
  left: 50%;
  bottom: 5%;
  transform: rotateZ(var(--rotateZ-plane));
  transition: transform 0.1s ease-in-out;
}
.model {
  width: 70vw;
  position: fixed;
  left: 25%;
  bottom: 13%;
  display: flex;
  flex-flow: row;
  justify-content: space-between;
  .model-item {
    width: 40%;
    display: flex;
    flex-flow: row;
    justify-content: center;
    align-items: center;
  }
}
.plane img {
  width: 100%;
  height: 100%;
  transform: rotateX(var(--rotateX-plane));
}
</style>
